package com.ysz.timewheel.server.task;

import com.ysz.timewheel.TimeWheel;
import com.ysz.timewheel.server.struct.ClientStruct;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @ClassName AcceptTask
 * @Description TODO
 * @Data 14:56
 * @Version 1.0
 * @Author ysz
 */
public class AcceptTask implements Runnable {
    /**
     * 任务队列
     */
    private static final LinkedBlockingQueue<AcceptTask> linkedBlockingQueue = new LinkedBlockingQueue<>();
    /**
     * 任务结果 1,2
     */
    private Integer returnCode;
    /**
     * 时间轮节点下标
     */
    private Integer currIndex;
    /**
     * 客户端结构体
     */
    private ClientStruct clientStruct;

    /**
     * 不断扫描超时map和失活map并返回状态 1,2
     *
     * @author ysz
     * @date 2022/2/23 16:04
     */
    @Override
    public void run() {
        try {
            while (true) {
                //从队列取值 如果队列没值会阻塞等待
                AcceptTask task = linkedBlockingQueue.take();
                if (Objects.isNull(task.getClientStruct()) || StringUtils.isEmpty(task.getClientStruct().getIp())) {
                    throw new IllegalArgumentException("无效参数");
                }
                //serverConn可能在睡完了直接中断  中断后此处没必要继续轮询处理了
                //直接将该task从队列移除就可以
                if (task.getClientStruct().getThread().isInterrupted()) {
                    linkedBlockingQueue.remove(task);
                }
                List<ClientStruct> clientStructs = null;
                //失活map中没有该节点后即可中断长轮询
                if (Objects.isNull(TimeWheel.getDeactivationClientsTime().get(task.getClientStruct()))) {
                    task.setReturnCode(2);
                    //中断线程
                    task.getClientStruct().getThread().interrupt();
                } else if ((clientStructs = TimeWheel.getTimeOutTimeClients().get(task.getCurrIndex())) != null && clientStructs.size() > 0) {
                    //过期map中没有该节点后即可中断长轮询
                    if (!clientStructs.contains(task.getClientStruct())) {
                        task.setReturnCode(1);
                        //中断线程
                        task.getClientStruct().getThread().interrupt();
                    } else {
                        //循环一次后如果线程没有中断需要把任务继续加回队列
                        linkedBlockingQueue.put(task);
                    }
                } else {
                    //循环一次后如果线程没有中断需要把任务继续加回队列
                    linkedBlockingQueue.put(task);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public Integer getReturnCode() {
        return returnCode;
    }

    public void setReturnCode(Integer returnCode) {
        this.returnCode = returnCode;
    }

    public Integer getCurrIndex() {
        return currIndex;
    }

    public void setCurrIndex(Integer currIndex) {
        this.currIndex = currIndex;
    }

    public ClientStruct getClientStruct() {
        return clientStruct;
    }

    public void setClientStruct(ClientStruct clientStruct) {
        this.clientStruct = clientStruct;
    }

    public static LinkedBlockingQueue<AcceptTask> getLinkedBlockingQueue() {
        return linkedBlockingQueue;
    }
}
